package com.seanLab.tool;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.seanLab.domain.SpecialImage;
import com.seanLab.domain.TagInfo;
import com.seanLab.dto.RecommendImageDto;
import com.seanLab.dto.RecommendTagInfoDto;
import com.seanLab.repository.SpecialImageRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.*;
import java.util.*;
import java.util.logging.Logger;

/**
 * 专家推荐/策略推荐接口
 * Created by BodeNg on 2018/5/4.
 */
@Component
public class ExpertsSuggestor {
    private final static String rawFile = "策略词典.json";
//    private final static String dicFile = "workingDir/策略词典real.json";
    @Value("${com.dasLab.model.expertDic}")
    private String dicFile;
    private final static Logger LOG = Logger.getLogger(ExpertsSuggestor.class.getName());

    private static HashMap<Integer, LinkedHashMap<String, ArrayList<String>>> expertDic = null;
    private static Random random = new Random(System.currentTimeMillis());

    @Autowired
    private SpecialImageRepo specialImageRepo;

    @PostConstruct
    public void init() {
        LOG.info("check and init expert dict: " + dicFile);
        JsonParser parser = new JsonParser();
        List<JsonObject> jsons = new ArrayList<>();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(dicFile)));
            String line;
            while ((line = br.readLine()) != null) {
                jsons.add(parser.parse(line).getAsJsonObject());
            }
            br.close();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dicFile)));
            for (JsonObject json : jsons) {
                if (!json.has("imgID")) {
                    json.addProperty("imgID", "imageID-" + UUID.randomUUID().toString());
                    specialImageRepo.save(dicImageToSpecialImage(json));
                }
                bw.write(json.toString());
                bw.newLine();
            }
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (expertDic == null) {
            expertDic = new HashMap<>();
            for (JsonObject json : jsons) {
                int cat = json.get("category").getAsInt();
                expertDic.putIfAbsent(cat, new LinkedHashMap<>());
                HashMap<String, ArrayList<String>> catMap = expertDic.get(cat);
                for (JsonElement key : json.get("key").getAsJsonArray()) {
                    String tag = key.getAsString();
                    catMap.putIfAbsent(tag, new ArrayList<>());
                    catMap.get(tag).add(json.get("imgID").getAsString());
                }
            }
        }

    }

    public SpecialImage dicImageToSpecialImage(JsonObject json) {
        SpecialImage image = new SpecialImage();
        image.setImgID(json.get("imgID").getAsString());
        image.setImgURL(json.get("imgURL").getAsString());
        image.setImgOriginalURL(json.get("imgURL").getAsString());
        image.setImgDescription("策略图库-" + String.valueOf(json.get("category").getAsInt()));
        image.setImgSource("expert");
        image.setImgCategory(new ArrayList<>());
        List<TagInfo> tagInfos = new ArrayList<>();
        for (JsonElement tag : json.get("key").getAsJsonArray()) {
            tagInfos.add(new TagInfo("tagID-" + UUID.randomUUID().toString(), tag.getAsString(), "expert", 10.0, 0));
        }
        image.setImgTagList(tagInfos);
        image.setArticleTitle("");
        image.setArticleURL("");
        image.setDeprecatedFlag(0);
        image.setImgType(1);
        image.setEsFlag(0);
        image.setImgTopic(new ArrayList<>());
        image.setTopTopics(new ArrayList<>());
        return image;
    }

    public RecommendImageDto recommendImage(String title, int category) {
        String match = findMatch(title, category);
        if (match != null) {
            String id = pickImage(match, category);
            SpecialImage image = specialImageRepo.findByImgID(id);
            if (image == null) {
                return null;
            }
            RecommendImageDto recommendImage = new RecommendImageDto();
            recommendImage.setImgID(image.getImgID());
            recommendImage.setArticleID(image.getArticleID());
            recommendImage.setImgOriginalURL(image.getImgOriginalURL());
            recommendImage.setImgURL(image.getImgURL());
            recommendImage.setImgSource(image.getImgSource());

            List<RecommendTagInfoDto> recommendTagInfoDtos = new ArrayList<>();
            for (TagInfo tagInfo : image.getImgTagList()) {
                RecommendTagInfoDto newTagInfo = new RecommendTagInfoDto();
                newTagInfo.setTagID(tagInfo.getTagID());
                newTagInfo.setTagName(tagInfo.getTagName());
                recommendTagInfoDtos.add(newTagInfo);
            }

            recommendImage.setImgTagList(recommendTagInfoDtos);
            recommendImage.setImgScore(99.99);
            return recommendImage;
        }
        return null;
    }

    private String findMatch(String title, int category) {
        title = title.toLowerCase();
        if (!expertDic.containsKey(category)) {
            return null;
        }
        for (String key : expertDic.get(category).keySet()) {
            if (title.contains(key)) {
                return key;
            }
        }
        return null;
    }

    private String pickImage(String match, int category) {
        ArrayList<String> ids = expertDic.get(category).get(match);
        return ids.get(random.nextInt(ids.size()));
    }

    public static void turnExpertDic(String rawPath) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(rawPath)));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(rawPath.replace(".json", "real.json"))));
            String line;
            List<String> datas = new ArrayList<>();
            int category = 0;
            JsonArray keys = new JsonArray();
            while ((line = br.readLine()) != null) {
                if (!line.startsWith("http")) {
                    String[] ele = line.split("\\s");
                    category = Integer.valueOf(ele[0]);
                    keys = new JsonArray();
                    for (int i = 1; i < ele.length; i++) {
                        if (!ele[i].equals("")) {
                            keys.add(ele[i]);
                        }
                    }
                    continue;
                }
                JsonObject json = new JsonObject();
                json.add("key", keys);
                json.addProperty("category", category);
                json.addProperty("imgURL", line);
                bw.write(json.toString());
                bw.newLine();
            }


            bw.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class TurnExpertDic {
        public static void main(String[] args) {
            turnExpertDic(rawFile);
        }
    }
}
